package com.example;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyClassPathXmlApplicationContext implements MyBeanFactory{
    Map<String, Object> map = new HashMap<>();

    public MyClassPathXmlApplicationContext(String configLocation) throws IOException {
        String path = this.getClass().getClassLoader().getResource(configLocation).getPath();
        Document document = Jsoup.parse(new File(path), "UTF-8");

        Elements beans = document.select("bean");
        for (Element bean : beans) {
            String id = bean.attr("id");
            String className = bean.attr("class");
            System.out.println(id + " === " + className);

            // 这里简单模拟只有一个构造器参数的情况
            Element cae = bean.selectFirst("constructor-arg");
            try {
                if (cae == null) {
                    Constructor<?> declaredConstructor = Class.forName(className).getDeclaredConstructor();
                    Object o = declaredConstructor.newInstance();
                    map.put(id, o);
                } else {
                    String ref = cae.attr("ref");
                    Object refObject = map.get(ref);
                    Constructor<?> declaredConstructor = Class.forName(className).getDeclaredConstructor(refObject.getClass());
                    System.out.println("refObject.getClass() = " + refObject.getClass());
                    Object o = declaredConstructor.newInstance(refObject);
                    map.put(id, o);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public Object getBean(String name) {
        return map.get(name);
    }

    @Override
    public boolean containsBean(String name) {
        return map.get(name) != null;
    }

    @Override
    public Set<String> getBeanDefinitionNames() {
        if (map.isEmpty()) {
            return null;
        }

        return map.keySet();
    }
}
